﻿using System;
using System.Globalization;

namespace Com.Lancetinc.Evs.Helpers
{
    /// <summary>
    /// 日期工具类
    /// </summary>
    public static class DateUtil
    {
        /// <summary>
        /// yyyyMMdd
        /// </summary>
        public const string DateFormatStrYyyymmdd = "yyyyMMdd";

        /// <summary>
        /// yyyyMMddHHmmss
        /// </summary>
        public const string DateFormatStrYmdhms = "yyyyMMddHHmmss";

        /// <summary>
        /// yyyyMMddHHmmssfff
        /// </summary>
        public const string DateFormatStrYmdhmsf = "yyyyMMddHHmmssfff";

        /// <summary>
        /// HHmmss
        /// </summary>
        public const string DateFormatStrHhmmss = "HHmmss";

        /// <summary>
        /// yyyy-MM-dd
        /// </summary>
        public const string DateFormatStrYyyyMmDd = "yyyy-MM-dd";

        /// <summary>
        /// HH:mm:ss
        /// </summary>
        public const string DateFormatStrHhMmSs = "HH:mm:ss";

        /// <summary>
        /// yyyy-MM-dd HH:mm
        /// </summary>
        public const string DateFormatStrYyyyMmDdHhMm = "yyyy-MM-dd HH:mm";


        /// <summary>
        /// yyyy-MM-dd HH:mm:ss
        /// </summary>
        public const string DateFormatStrYyyyMmDdHhMmSs = "yyyy-MM-dd HH:mm:ss";

        /// <summary>
        /// 日期格式化
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="fmt"></param>
        /// <returns></returns>
        public static string Format(DateTime dt, string fmt = DateFormatStrYyyyMmDdHhMmSs)
        {
            return dt.ToString(fmt);
        }

        /// <summary>
        /// 是否是日期类型
        /// </summary>
        /// <param name="str">文字</param>
        /// <param name="fmt">文字格式</param>
        /// <returns></returns>
        public static bool IsDate(string str, string fmt = "")
        {
            return ToDate(str, fmt).HasValue;
        }

        /// <summary>
        /// 转换为日期类型。
        /// 如果转换失败，则返回null
        /// </summary>
        /// <param name="str">文字</param>
        /// <param name="fmt">格式</param>
        /// <returns></returns>
        public static DateTime? ToDate(string str, string fmt = "")
        {
            try
            {
                if (DateTime.TryParse(str, out var dtOut))
                {
                    return dtOut;
                }

                if (string.IsNullOrEmpty(fmt))
                {
                    str = str.Replace("/", "").Replace("-", "").Replace(" ", "");
                    if (str.Length == DateFormatStrYmdhmsf.Length)
                    {
                        if (DateTime.TryParseExact(str, DateFormatStrYmdhmsf, null, DateTimeStyles.None, out dtOut))
                        {
                            return dtOut;
                        }
                    }
                    else if (str.Length == DateFormatStrYmdhms.Length)
                    {
                        if (DateTime.TryParseExact(str, DateFormatStrYmdhms, null, DateTimeStyles.None, out dtOut))
                        {
                            return dtOut;
                        }
                    }
                    else if (str.Length == 12)
                    {
                        if (DateTime.TryParseExact(str, "yyyyMMddHHmm", null, DateTimeStyles.None, out dtOut))
                        {
                            return dtOut;
                        }
                    }
                    else if (str.Length == 8)
                    {
                        if (DateTime.TryParseExact(str, DateFormatStrYyyymmdd, null, DateTimeStyles.None, out dtOut))
                        {
                            return dtOut;
                        }
                    }
                    else if (str.Length == 6)
                    {
                        str = "20" + str;
                        if (DateTime.TryParseExact(str, DateFormatStrYyyymmdd, null, DateTimeStyles.None, out dtOut))
                        {
                            return dtOut;
                        }
                    }
                }
                else
                {
                    if (DateTime.TryParseExact(str, fmt, null, DateTimeStyles.None, out dtOut))
                    {
                        return dtOut;
                    }
                }

                return null;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 日期重新格式化
        /// </summary>
        /// <param name="dateStr">日期</param>
        /// <param name="fmt"></param>
        /// <param name="orgFmt">日期的原来格式</param>
        /// <returns></returns>
        public static string FormatDateString(string dateStr, string fmt, string orgFmt = "")
        {
            if (!string.IsNullOrEmpty(dateStr))
            {
                var dt = ToDate(dateStr, orgFmt);
                if (dt.HasValue)
                {
                    return dt.Value.ToString(fmt);
                }
            }

            return string.Empty;
        }

        /// <summary>
        /// 取得一天的开始
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime GetStartOfDate(DateTime dt)
        {
            return dt.Date;
        }

        /// <summary>
        /// 取得一天的结束
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime GetEndOfDate(DateTime dt)
        {
            return dt.Date.AddDays(1).AddMilliseconds(-1);
        }

        /// <summary>
        /// 把日期转换成数据库存储所需字符串
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string FormatForDbUpdate(this DateTime dt)
        {
            return dt.ToString("yyyy-MM-dd HH:mm:ss.fff");
        }
    }
}
